﻿#include "mem_Page.h"
#include<QFile>
#include<QTextStream>
#include"mainwindow.h"


void PAGE::dispatch_memory(process* PROCESS){
    PPCB *cur=PROCESS->waithead->next;
        while(cur!=PROCESS->waitrear){
            int need=cur->memory/page_size==0?cur->memory/page_size:cur->memory/page_size+1;   //计算该进程所需页数
            if(need<free_page){

                PAGETABLE* addr_pagetable = new PAGETABLE(need);
                cur->pagetable=addr_pagetable;                                         //为当前pcb分配一个新页表
                addr_pagetable->num_page=need;
                for(int i = 0, j = 0; i < addr_pagetable->num_page; i++){//进程每一个页项 i程序页号  j内存页号
                        while( used_pagemap[j] ){//跳过每一个用了的页
                            j++;
                        }
                    addr_pagetable->page_entry.push_back({i,j});
                    used_pagemap[j++] = 1;
                    free_page--;                                       //更新内存使用情况
                    used_frame+=page_size;
                    Utilization=(float)used_frame/memory_size;
                }

                PPCB *next=cur;                     //记录等待队列位置
                cur=cur->next;
                PROCESS->Delete_process_byId(next->id,2);
                PROCESS->Insert_ready(next);
            }
           else
                cur=cur->next;
        }


}


void PAGE::Delete(process* PROCESS){
    PPCB *cur=PROCESS->finishhead->next;

        while(cur!=PROCESS->finishrear){
            PAGETABLE *table=cur->pagetable;                          //当前pcb对应的页表
            for(int i=0;i<table->num_page;i++){
                used_pagemap[table->page_entry[i][0]]=0;             //释放内存
                free_page++;                                       //更新内存使用情况
                used_frame-=page_size;
                Utilization=(float)used_frame/memory_size;
            }
            cur->pagetable=NULL;                                 //丢弃当前进程对应的页表
            PPCB *next=cur;                     //记录完成队列位置
            cur=cur->next;
            PROCESS->Delete_process_byId(next->id,5);      //从完成队列中删除进程
        }
}
